package com.jeesite.modules.kj.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ListObjectsV2Request;
import com.aliyun.oss.model.ListObjectsV2Result;
import com.aliyun.oss.model.OSSObjectSummary;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.FileInputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * @author wangzhenjun
 */
public class SearchUtil {
    public static void main(String[] args) {
        try {
            String tempPath = "/";
            String os = System.getProperty("os.name");
            if (os.toLowerCase().startsWith("windows")) {
                tempPath = "\\";
            }
            String nowPath = System.getProperty("user.dir");
            File file = new File(nowPath + tempPath + "ossConfig.json");
            JSONObject configObj = JSON.parseObject(IOUtils.toString(new FileInputStream(file), StandardCharsets.UTF_8));
            String endpoint = (String) configObj.getOrDefault("endpoint", "https://oss-cn-hangzhou.aliyuncs.com");
            String accessKeyId = configObj.getString("accessKeyId");
            String accessKeySecret = configObj.getString("accessKeySecret");
            String bucketName = configObj.getString("bucketName");
            String searchKey = configObj.getString("searchKey");
            String[] partArr = searchKey.split("/", -1);
            String delimiter = (String) configObj.getOrDefault("delimiter", "/");
            int keyNum = partArr.length;

            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            ListObjectsV2Request params = new ListObjectsV2Request();
            params.setDelimiter(delimiter);
            params.setBucketName(bucketName);
            params.setMaxKeys(1000);

            List<String> keyList = new ArrayList<>();
            dfs(keyList, 0, partArr, 1, keyNum, configObj, new ArrayList<>(), ossClient, params);
            params.setDelimiter(delimiter);
            try {
                List<String> retList = new ArrayList<>();
                for (String key : keyList) {
                    params.setPrefix(key);
                    requestOss(params, ossClient, retList);
                }
                for (String s : retList) {
                    System.err.println(s);
                }
            } catch (Exception oe) {
                oe.printStackTrace();
            } finally {
                if (ossClient != null) {
                    ossClient.shutdown();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void requestOss(ListObjectsV2Request params, OSS ossClient, List<String> retList) {
        ListObjectsV2Result objectListing = ossClient.listObjectsV2(params);
        List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
        for (OSSObjectSummary s : sums) {
            retList.add(s.getKey());
        }
        retList.addAll(objectListing.getCommonPrefixes());
    }

    private static void dfs(List<String> keyList, int sNum, String[] partArr, int dfsNum, int totalDfsNum,
                            JSONObject configObj, List<String> values, OSS ossClient, ListObjectsV2Request params) {
        if (dfsNum > totalDfsNum) {
            keyList.add(StringUtils.join(values, "/"));
        } else {
            String partItem = partArr[dfsNum - 1];
            if (partItem.endsWith("%s")) {
                // 处理匹配数据: %s
                sNum++;
                List<String> tempList = getList(configObj.getString("keys" + sNum));
                for (String s : tempList) {
                    values.add(s);
                    dfs(keyList, sNum, partArr, dfsNum + 1, totalDfsNum, configObj, values, ossClient, params);
                    values.remove(values.size() - 1);
                }
            } else if ("*".equals(partItem)) {
                // 处理通配符: *
                List<String> partItemResultList = new ArrayList<>();
                params.setPrefix(StringUtils.join(values, "/") + "/");
                params.setDelimiter("/");
                requestOss(params, ossClient, partItemResultList);
                for (String s : partItemResultList) {
                    String[] tempArr = s.split("/");
                    values.add(tempArr[tempArr.length - 1]);
                    dfs(keyList, sNum, partArr, dfsNum + 1, totalDfsNum, configObj, values, ossClient, params);
                    values.remove(values.size() - 1);
                }
            } else {
                // 处理字符串
                values.add(partItem);
                dfs(keyList, sNum, partArr, dfsNum + 1, totalDfsNum, configObj, values, ossClient, params);
                values.remove(values.size() - 1);
            }
        }
    }

    private static List<String> getList(String srcStr) {
        List<String> retList = new ArrayList<>();
        String[] arr = srcStr.split(",");
        for (String s : arr) {
            if (StringUtils.isNotBlank(s)) {
                retList.add(s.trim());
            }
        }
        return retList;
    }
}
